<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport"
    content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  <title>2048 面包版</title>
  <link rel="stylesheet" type="text/css" href="./css/2048.css"/>
  <script src="./jqm/jquery-1.11.1.min.js"></script>
  <script src="./js/support2048.js"></script>
  <script src="./js/showanimation2048.js"></script>
  <script src="./js/main2048.js"></script>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      height: 100%;
      background: #faf8ef;
      font-family: Arial, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    #grid-container {
      position: relative;
      width: 320px;
      height: 320px;
      margin-top: 20px;
      background: #bbada0;
      border-radius: 6px;
    }
    .grid-cell {
      width: 64px;
      height: 64px;
      background: rgba(238, 228, 218, 0.35);
      border-radius: 6px;
      position: absolute;
      border: 2px solid #bbada0; /* 增加边框宽度，使网格线更明显 */
      box-sizing: border-box; /* 确保边框不影响单元格尺寸 */
    }
    .number-cell {
      position: absolute;
      border-radius: 6px;
      text-align: center;
      font-weight: bold;
    }
    #title {
      margin-top: 30px;
      font-size: 36px;
      color: #776e65;
    }
    #newgamebutton {
      margin-top: 10px;
      padding: 10px 20px;
      background-color: #f59563;
      color: white;
      border: none;
      border-radius: 6px;
      font-size: 16px;
      cursor: pointer;
    }
    #scoreText {
      margin-top: 10px;
      color: #776e65;
    }
    #leaderboard {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 240px;
      background: #fff3dc;
      border-radius: 12px;
      padding: 20px;
      font-size: 14px;
      box-shadow: 0 0 10px rgba(0,0,0,0.2);
      z-index: 999;
      opacity: 0;
      pointer-events: none; /* 禁用鼠标事件 */
      transition: opacity 0.3s ease; /* 添加过渡效果 */
    }
    #leaderboard.active {
      opacity: 1;
      pointer-events: auto; /* 启用鼠标事件 */
    }
    #leaderboard h3 {
      margin-top: 0;
      font-size: 18px;
      text-align: center;
    }
    #leaderboard-list {
      list-style: decimal inside;
      margin: 0;
      padding: 0;
      max-height: 300px;
      overflow-y: auto;
    }
    #leaderboard-list li {
      padding: 4px 0;
      word-break: break-word;
    }
    #leaderboard button {
      width: 100%;
      margin-top: 10px;
      padding: 6px;
      font-size: 13px;
      border: none;
      border-radius: 6px;
      background: #f59563;
      color: white;
    }
    #showLeaderboardBtn {
      position: fixed;
      bottom: 50px;
      right: 20px;
      background: #8f7a66;
      color: white;
      padding: 10px 14px;
      font-size: 14px;
      border-radius: 50px;
      border: none;
      cursor: pointer;
      z-index: 900; /* 确保按钮在其他元素上方 */
    }
    #name-popup {
      display: none;
      position: fixed;
      top: 40%;
      left: 50%;
      transform: translate(-50%,-50%);
      background: #fff;
      padding: 20px;
      border-radius: 10px;
      box-shadow: 0 0 10px rgba(0,0,0,0.3);
      z-index: 1000;
      text-align: center;
    }
    footer {
      position: fixed;
      bottom: 10px;
      width: 100%;
      text-align: center;
      color: #776e65;
      font-size: 12px;
      z-index: 800; /* 确保footer在排行榜按钮下方 */
    }
  </style>
</head>
<body>
  <h1 id="title">2048 面包版</h1>
  <button id="newgamebutton" onclick="canScroll = false; newgame();">再来</button>
  <p id="scoreText">你的超话等级是 <span id="position">挑战</span> — 经验值: <span id="score">0</span> 点</p>
  <div id="grid-container"></div>
  <button id="showLeaderboardBtn" onclick="toggleLeaderboard()">排行榜</button>
  <div id="leaderboard">
    <h3>排行榜</h3>
    <div id="leaderboard-scroll">
      <ol id="leaderboard-list"></ol>
    </div>
    <button onclick="toggleLeaderboard()">关闭</button>
  </div>

 <div id="name-popup">
    <p style="margin-bottom:10px;">游戏结束！请输入你的昵称：</p>
    <input type="text" id="playerNameInput" placeholder="玩家昵称" style="width:80%;padding:6px;" />
    <br><br>
    <button onclick="submitPlayerName()" style="padding:6px 20px;background:#f59563;color:white;border:none;border-radius:6px;">提交</button>
  </div>
  <script>
    // 防止页面上滑和右滑返回
    var touchStartX = 0;
    var canScroll = false; // 控制是否允许滚动的标志
    
    document.addEventListener('touchmove', function(e) {
        if (!canScroll) {
            e.preventDefault();
        }
    }, { passive: false });
    
    document.addEventListener('touchstart', function(e) {
        touchStartX = e.touches[0].clientX;
    }, false);
    
    document.addEventListener('touchmove', function(e) {
        if (!canScroll) {
            var touchX = e.touches[0].clientX;
            var diffX = touchX - touchStartX;
            
            if (diffX > 50) { // 向右滑动距离超过50px时阻止
                e.preventDefault();
            }
        }
    }, { passive: false });

    // 存储CSRF令牌和会话状态
    let csrfToken = null;
    let sessionInitialized = false;
    
    /* 游戏变量（全局作用域）
var board = [];
var score = 0;
var gameOverTriggered = false; // 只声明一次
var isGameOverFlag = false;*/
    
    // 页面加载后初始化游戏和获取CSRF令牌
    window.addEventListener('load', function() {
      canScroll = false;
      newgame();
      initializeSession();
    });
    
    // 初始化会话和获取CSRF令牌
    function initializeSession() {
      return new Promise((resolve, reject) => {
        // 先发送一个初始化请求，确保会话已启动
        $.get("./init_session.php")
          .done(function() {
            sessionInitialized = true;
            // 再获取CSRF令牌
            fetchCSRFToken().then(resolve).catch(reject);
          })
          .fail(function(jqXHR, textStatus, errorThrown) {
            console.error("会话初始化失败:", textStatus, errorThrown);
            sessionInitialized = false;
            reject(new Error("会话初始化失败"));
          });
      });
    }
    
    // 获取CSRF令牌
    function fetchCSRFToken() {
      return new Promise((resolve, reject) => {
        if (!sessionInitialized) {
          reject(new Error("会话未初始化"));
          return;
        }
        
        $.get("./get_token.php")
          .done(function(data) {
            if (data.token) {
              csrfToken = data.token;
              console.log("CSRF令牌获取成功");
              resolve(data.token);
            } else {
              console.error("CSRF令牌获取失败:", data);
              reject(new Error("CSRF令牌格式不正确"));
            }
          })
          .fail(function(jqXHR, textStatus, errorThrown) {
            console.error("获取CSRF令牌请求失败:", textStatus, errorThrown);
            reject(new Error("获取CSRF令牌失败"));
          });
      });
    }
    
    // 确保CSRF令牌有效的函数
    function ensureValidCSRFToken() {
      return new Promise((resolve, reject) => {
        if (csrfToken) {
          resolve(csrfToken);
        } else {
          initializeSession().then(token => resolve(token)).catch(reject);
        }
      });
    }

    function gameOver() {
  if (gameOverTriggered) return; // 直接使用全局变量
  gameOverTriggered = true;      // 直接赋值，不声明
  isGameOverFlag = true;
  canScroll = true;
  setTimeout(() => {
    document.getElementById('name-popup').style.display = 'block';
  }, 300);
}

    function submitPlayerName() {
      const name = document.getElementById("playerNameInput").value || "玩家";
      saveToLeaderboard(name, score);
      document.getElementById('name-popup').style.display = 'none';
    }

    function saveToLeaderboard(name, score) {
      ensureValidCSRFToken()
        .then(token => {
          return $.post("./leaderboard.php?action=add", {
            name: name,
            score: score,
            csrf_token: token
          });
        })
        .done(function(res) {
          console.log("排行榜提交成功：", res);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
          console.error("提交失败:", textStatus, errorThrown);
          
          if (jqXHR.status === 403) {
            console.error("CSRF验证失败，重新初始化会话和令牌");
            csrfToken = null; // 重置令牌
            initializeSession()
              .then(() => alert("安全验证已重置，请重试"))
              .catch(err => alert("安全验证失败: " + err.message));
          } else {
            alert("提交失败: " + textStatus);
          }
        });
    }

     function renderLeaderboard() {
      $.get("./leaderboard.php?action=get", function(data) {
        try {
          const parsed = typeof data === "string" ? JSON.parse(data) : data;
          const list = document.getElementById("leaderboard-list");
          list.innerHTML = "";
    
          if (parsed.length === 0) {
            const li = document.createElement("li");
            li.textContent = "暂无记录";
            list.appendChild(li);
          } else {
            parsed.forEach(entry => {
              const li = document.createElement("li");
              li.textContent = `${entry.name} - ${entry.score}分`;
              list.appendChild(li);
            });
          }
    
        } catch (e) {
          console.error("排行榜数据解析失败：", e);
          console.error("服务器返回的数据：", data);
          alert("排行榜加载失败：" + e);
        }
      }).fail(function(jqXHR, textStatus, errorThrown) {
        console.error("排行榜请求失败：", textStatus, errorThrown);
        alert("排行榜请求失败：" + textStatus);
      });
    }

    function toggleLeaderboard() {
      const lb = document.getElementById('leaderboard');
      if (lb.classList.contains('active')) {
        lb.classList.remove('active');
      } else {
        renderLeaderboard();
        lb.classList.add('active');
      }
    }
  </script>
  <footer>
    <p>
      <a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">赣ICP备2025063750号-1</a>
    </p>
  </footer>
</body>
</html>
